﻿using Comm100.Framework.Domain.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bot.Domain.Entities;
using Bot.Domain.Interfaces;
using Bot.Domain.Bo;
using Castle.Windsor;
using Bot.Domain.Specifications;
using Bot.Domain.BotImport;
using Newtonsoft.Json;
using AutoMapper;
using Bot.Domain.Enum;

namespace Bot.Domain.Categories.Service
{
    public class BackgroundJobDomainService : IBackgroundJobDomainService
    {
        private IWindsorContainer _container;
        private readonly IRepository<Guid, BackgroundJob> _repository;
        public IMapper Mapper { get; set; }

        public BackgroundJobDomainService(IRepository<Guid, BackgroundJob> repository, IWindsorContainer container)
        {
            this._repository = repository;
            this._container = container;
        }

        public BackgroundJob Create(BackgroundJob category)
        {
            return _repository.Create(category);
        }

        public BackgroundJob Get(Guid id)
        {
            return _repository.Get(id);
        }

        public BackgroundJob Update(BackgroundJobUpdateBo bo)
        {
            BackgroundJob backgroundJob = _repository.Get(bo.Id);
            backgroundJob.Id = bo.Id;
            backgroundJob.SiteId = bo.SiteId;
            backgroundJob.BotId = bo.BotId;
            backgroundJob.Type = bo.Type;
            backgroundJob.Content = bo.Content;
            backgroundJob.Attachment = bo.Attachment;
            backgroundJob.Status = bo.Status;
            backgroundJob.CreatedTime = bo.CreatedTime;

            return backgroundJob;

        }

        public IEnumerable<BackgroundJob> List()
        {
            return _repository.ListAll();
        }

        public void Delete(Guid id)
        {
            if (_repository.Exists(id))
            {
                BackgroundJob backgroundJob = _repository.Get(id);

                _repository.Delete(backgroundJob);
            }

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Operation GetOperation(Guid id)
        {
            Operation operation = new Operation { };
            
            var job = _repository.Get(id);
            OperateEntity operateEntity = JsonConvert.DeserializeObject<OperateEntity>(job.Content);

            if (operateEntity != null)
            {
                switch (operateEntity.OperateType)
                {
                    case EnumOperateType.importBot:
                        {
                            IChatbotDomainService chatbotDomainService = _container.Resolve<IChatbotDomainService>();
                            var bot = chatbotDomainService.Get(job.BotId);
                            operation = chatbotDomainService.Import(id, "", bot);
                            if (operation.Status == Enum.EnumOperationStatus.Succeeded)
                            {
                                //_agentBotCacheAppService.Update(siteId, Com.Comm100.Public.Bot.AgentBot.EnumUpdateType.AIChatBot, botDto.Id);

                                //ServerCacheProcessHandle.UploadChatServerCodePlanCache(EnumServerCacheUpdateActionType.AiBotUpdated, siteId, Guid.Empty);
                            }

                            break;
                        }
                    case EnumOperateType.trainBot:
                        {
                            IBotApiService botApiService = _container.Resolve<IBotApiService>();
                            IChatbotDomainService chatbotDomainService = _container.Resolve<IChatbotDomainService>();
                            var bot = chatbotDomainService.Get(job.BotId);
                            var botDto = Mapper.Map<Bot.BotDto>(bot);

                            var result = botApiService.GetOperations(botDto, operateEntity.OperationName).Result;
                            if (result.IsSuccess)
                            {
                                if (result.Data == null)
                                {
                                    operation.Status = Enum.EnumOperationStatus.Succeeded;
                                    chatbotDomainService.SetBotAsTrained(bot.Id);
                                }
                                else
                                {
                                    operation.Status = Enum.EnumOperationStatus.Processing;
                                }
                            }
                            else
                            {
                                operation.Status = Enum.EnumOperationStatus.Failed;
                                operation.ErrorMessage = result.Error.Message;
                            }
                            break;
                        }
                    case EnumOperateType.importIntent:
                        {
                            IChatbotDomainService chatbotDomainService = _container.Resolve<IChatbotDomainService>();
                            IIntentDomainService intentDomainService = _container.Resolve<IIntentDomainService>();
                            var bot = chatbotDomainService.Get(job.BotId);
                            EnumImportMode model = operateEntity.Mode;                          

                            operation = intentDomainService.Import(job.Id, "", bot, model);
                            if (operation.Status == EnumOperationStatus.Succeeded ||
                                operation.Status == EnumOperationStatus.Failed)
                            {
                                //ServerCacheProcessHandle.UploadChatServerCodePlanCache(EnumServerCacheUpdateActionType.AiBotUpdated, siteId, Guid.Empty);
                                if(operation.Status == EnumOperationStatus.Succeeded)
                                {
                                    //_agentBotCacheAppService.Update(siteId, Com.Comm100.Public.Bot.AgentBot.EnumUpdateType.AIChatBotIntent, botDto.Id);
                                }
                            }
                            break;
                        }
                    case EnumOperateType.importEntity:
                        {
                            IChatbotDomainService chatbotDomainService = _container.Resolve<IChatbotDomainService>();
                            IEntityDomainService entityDomainService = _container.Resolve<IEntityDomainService>();
                            var bot = chatbotDomainService.Get(job.BotId);

                            operation = entityDomainService.Import(job.Id, bot, "");
                            if (operation.Status == EnumOperationStatus.Succeeded ||
                                operation.Status == EnumOperationStatus.Failed)
                            {                                
                                //ServerCacheProcessHandle.UploadChatServerCodePlanCache(EnumServerCacheUpdateActionType.AiBotUpdated, siteId, Guid.Empty);
                            }
                            break;
                        }
                    case EnumOperateType.importAiLearningQuestions:
                        {
                            operation.Status = job.Status;
                            operation.Percent = operateEntity.Percent;
                            if(job.Status == EnumOperationStatus.Failed)
                            {
                                operation.ErrorMessage = operateEntity.ErrorMessage;
                            }
                            break;
                        }
                }
            }

            return operation;
        }
        public bool ExistsJob(Guid id)
        {
            return _repository.Count(new BackgroundJobFilterSpecification(id)) > 0;
        }
    }
}
